from django.contrib.auth import login,authenticate,logout
from django.contrib.auth.models import User, Group, Permission
from django.shortcuts import render_to_response, redirect
from comunidadcyt.Registration_Users.forms import LoginForm,CreateProfileForm,UserForm,UserCreationFormExtended,UserTypeForm
from django.core.context_processors import csrf
from django.http import HttpResponseRedirect
from django.template.context import RequestContext
from django.core.exceptions import ObjectDoesNotExist
from comunidadcyt.Registration_Users.models import UserProfile
from django.contrib.auth.models import Group as DjangoGroup
from django.core.urlresolvers import reverse
from django.utils import simplejson
from django.db import IntegrityError
from django.http import HttpResponse
from comunidadcyt.views import index
from django.db.models import Q
from comunidadcyt.Publicaciones.models import   Libros, Conferencias, Papers, Tesis, Revistas, ReportesTecnicos
from comunidadcyt.cargoAcademico.models import CargoAcademico
from comunidadcyt.views import index as go_home

def login_view(request):
    c = {}
    if request.method == 'POST':
        form = LoginForm(request.POST.copy())
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            current_path = form.cleaned_data['current_path_login']
            user = authenticate(username=username,password=password)


            if user is not None:
                if user.is_active:
                    login(request, user)
                    return redirect(current_path)
                else:
                    form = LoginForm()
                    c.update(csrf(request))
                    c.update({'form':form})
                    c.update({'user':request.user})
                    c.update({'msg':"Tu cuenta aun no fue activada por el administrador del sitio."})
                    return render_to_response('Registration_Users/login_error.html',c)
            else:
                form = LoginForm()
                c.update(csrf(request))
                c.update({'form':form})
                c.update({'user':request.user})
                c.update({'msg':"Ha ingresado un nombre de usuario y/o password invalido."})
                return render_to_response('Registration_Users/login_error.html',c)

    else:
        form = LoginForm()
    c.update(csrf(request))
    c.update({'form':form})
    c.update({'user':request.user})
    return render_to_response('Registration_Users/index.html',c)

def logout_view(request):
    logout(request)
    return HttpResponseRedirect(reverse(go_home))

def register_view(request):
    c = {}
    request.breadcrumbs('Registrarse',request.path)
    if request.method == 'POST':
        form = UserCreationFormExtended(request.POST.copy())
        if form.is_valid():
            u = form.save()

            np = UserProfile(user = u)
            np.motivo = form.cleaned_data['motivo']
            np.save()

            u.is_active = False
            u.save()

            return render_to_response('Registration_Users/success.html',context_instance = RequestContext(request))
    else:
        form = UserCreationFormExtended()
    
    c.update({'form':form})
    c.update(csrf(request))
    c.update({'user':request.user})

    return render_to_response('Registration_Users/register.html',c,context_instance = RequestContext(request))

def disable_user(request, object_id=0):
    if request.user.is_superuser:
        try:
            u = User.objects.get(id = object_id)

            if u:
                if request.method == "GET":
                    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Desabilitar Usuario',request.path)])

                    return render_to_response(
                        'Registration_Users/confirm_disable_user.html',
                        {'iduser_disable': object_id},
                        context_instance = RequestContext(request)
                    )
                elif request.method == "POST":
                    try:
                        u.is_active = False
                        u.save()
                    except:
                        pass
                    return HttpResponseRedirect('/comunidadcyt/accounts/profileSummary/%s' % str(u.id))
        except ObjectDoesNotExist:
            pass

    return HttpResponseRedirect('/')

def show_user_resume(request,user_id):
    c = {}
    c.update({'user':request.user})
    try:
        u = User.objects.get(id = user_id)
        p = u.get_profile()
        if p.cv is not None:
            response = HttpResponse(p.cv,mimetype = 'application/pdf')
            response['Content-Disposition'] = 'inline; filename=%s' % p.cv
            return response
        else:
            return redirect(reverse(view_profile_view(request)))
    except ObjectDoesNotExist:
        c.update({'errors': 'No existe el perfil solicitado'})
        c.update({'text_to_show':'Click aqui para volver al inicio'})
        c.update({'redirect_page':'/comunidadcyt/home'})
        return render_to_response('Registration_Users/error.html',c)

def view_profile_view(request):
    c={}
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Ver Perfil',request.path)])
    try:
        profile = request.user.get_profile()
        c.update({'profile':profile})
        c.update({'user':request.user})
        c.update({'other':False})
        return render_to_response('Registration_Users/view_profile.html',c,context_instance = RequestContext(request))
    except ObjectDoesNotExist:
        c.update({'errors':'Todavia no te creaste un perfil??',
                  'text_to_show':'Click aqui para crear perfil',
                  'redirect_page':'/comunidadcyt/accounts/createProfile/'})
        return render_to_response('Registration_Users/error.html',c,context_instance = RequestContext(request))

def view_another_users_profile(request,user_id):
    c = {}
    try:
        u = User.objects.get(id = user_id)
        p = u.get_profile()
        c.update({'profile':p})
        c.update({'anuser':u})
    except ObjectDoesNotExist:
        c.update({'error':True})
        
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Perfil de ' + u.get_full_name() if u else "Perfil", request.path)])
        
    c.update({'other':True})
    return render_to_response('Registration_Users/view_profile.html',c,context_instance = RequestContext(request))

def create_profile(request):
    c = {}
    request.breadcrumbs([('Perfil',reverse(view_profile_view)),('Crear Perfil de '+ request.user.get_full_name(),request.path)])
    if request.method=='POST':
        form = CreateProfileForm(request.user, request.POST,request.FILES)
        if form.is_valid():
            form.save()
    else:
        form = CreateProfileForm(request.user)
        c.update(csrf(request))
        c.update({'form':form})
        c.update({'user':request.user})

        return render_to_response('Registration_Users/profile.html',c)

    return HttpResponseRedirect(reverse(view_profile_view))

def profile_edit_view(request):
    c = {}
    request.breadcrumbs([('Perfil',reverse(view_profile_view)),('Editar Perfil de '+ request.user.get_full_name(),request.path)])
    if request.method=='POST':
        form = CreateProfileForm(request.user, request.POST, request.FILES, instance = request.user.get_profile())
        if form.is_valid():
            form.save()
    else:
        try:
            profile = request.user.get_profile()
            request.breadcrumbs([('Perfil',reverse(view_profile_view)),('Editar Perfil', request.path)])
            form = CreateProfileForm(request.user, instance=profile)
            form2 = UserForm(request.user, instance=request.user)
            c.update(csrf(request))
            c.update({'form':form})
            c.update({'form2':form2})
            c.update({'user':request.user})
            return render_to_response('Registration_Users/profile.html',c)
        except ObjectDoesNotExist:
            pass
    return HttpResponseRedirect(reverse(view_profile_view))

def namemail_edit(request):
    if request.method=='POST':
        form = UserForm(request.user, request.POST, request.FILES, instance = request.user)
        if form.is_valid():
            form.save()

    return HttpResponseRedirect(reverse(view_profile_view))

def login_xhr_view(request,key_xhr):
    response_dict = {}
    username = request.POST.__getitem__('username')
    password = request.POST.__getitem__('password')
    
    user = authenticate(username=username,password=password)
    
    if user is not None:
        if user.is_active:
            login(request, user)
            response_dict.update({'ok': True})
        else:
            response_dict.update({'errors':'No esta registrado o activo'})
    else:
        response_dict.update({'errors':'No esta registrado o activo'})
    
    return HttpResponse(simplejson.dumps(response_dict),
                        mimetype = 'application/javascript')

def ajax_list_users_view(request,key_xhr):
    response_dict = {}
    lista = []
    
    for eu in User.objects.all():
        lista.append(eu.get_full_name())
    
    response_dict.update({'ok':True})
    response_dict.update({'list':lista})
    
    return HttpResponse(simplejson.dumps(response_dict),mimetype = 'application/javascript')

def listar_usuarios(request):
    request.breadcrumbs([('Usuarios',request.path)])
    u = User.objects.all().order_by('first_name', 'last_name')
    user_list = []
    for users in u: 
        user_list.append({'euser':users})
        
    return render_to_response('Registration_Users/listar_usuarios.html',{'user':request.user,'user_list':user_list},context_instance=RequestContext(request))

def obtenerUsuario(request,object_id):
    if int(object_id):
        try:
            objectoUsuario = User.objects.get(id=object_id)
        except ObjectDoesNotExist:
            return 'No existe el objecto usuario'
    else:
        return 'No existe el objecto usuario'
    return objectoUsuario

def obtenerDeptos(usuario):
    list_grupos = usuario.grupos.all()
    list_departamentos = []
    for proyecto in usuario.proyectos.all():
        lista = proyecto.Departamentos.all()
        for obj in lista:
            if not list_departamentos.__contains__(obj):
                list_departamentos += [obj]
        for proy in proyecto.Grupos.all():
            if not list_grupos.__contains__(proy):
                list_grupos += [proy]
    for grupo in list_grupos:
        if not list_departamentos.__contains__(grupo.Departamento):
            list_departamentos += [grupo.Departamento]
    return list_departamentos

def obtenerEventos(usuario):
    deptos = obtenerDeptos(usuario)
    grupos = usuario.grupos.all()
    list_eventos = []
    for dep in deptos:
        for ev in dep.eventos.all():
            if ev not in list_eventos:
                list_eventos.append(ev)
    for gru in grupos:
        for ev in gru.eventos.all():
            if ev not in list_eventos:
                list_eventos.append(ev)
    return list_eventos

def listareventos(request, object_id=0):
    usuario = obtenerUsuario(request, object_id)
    if usuario == 'No existe el objecto usuario':
        return render_to_response('error.html',{'error':'No existe el objecto usuario', 'archivo': 'view de usuarios', 'linea': 'linea 20'})
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Listar Eventos de '+usuario.get_full_name(),request.path)])
    return render_to_response('Registration_Users/eventos.html', {'Usuario': usuario, 'list_eventos': obtenerEventos(usuario), 'user': request.user}, context_instance=RequestContext(request))

def listardeptos(request, object_id=0):
    usuario = obtenerUsuario(request, object_id)
    if usuario == 'No existe el objecto usuario':
        return render_to_response('error.html',{'error':'No existe el objecto usuario', 'archivo': 'view de usuarios', 'linea': 'linea 20'})
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Listar Departamentos de '+usuario.get_full_name(),request.path)])
    return render_to_response('Registration_Users/deptos.html', {'Usuario': usuario, 'list_deptos': obtenerDeptos(usuario), 'user': request.user}, context_instance=RequestContext(request))

def listarproyectos(request, object_id=0):
    usuario = obtenerUsuario(request, object_id)
    if usuario == 'No existe el objecto usuario':
        return render_to_response('error.html',{'error':'No existe el objecto usuario', 'archivo': 'view de usuarios', 'linea': 'linea 20'})
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Listar Proyectos de '+usuario.get_full_name(),request.path)])
    return render_to_response('Registration_Users/proyectos.html', {'Usuario': usuario, 'list_proyectos': usuario.proyectos.all(), 'user': request.user}, context_instance=RequestContext(request))

def listargrupos(request, object_id=0):
    usuario = obtenerUsuario(request, object_id)
    if usuario == 'No existe el objecto usuario':
        return render_to_response('error.html',{'error':'No existe el objecto usuario', 'archivo': 'view de usuarios', 'linea': 'linea 20'})
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Listar Grupos de '+usuario.get_full_name(),request.path)])
    return render_to_response('Registration_Users/grupos.html', {'Usuario': usuario, 'list_grupos': usuario.grupos.all(), 'user': request.user}, context_instance=RequestContext(request))

def listarpublicaciones(request, object_id=0):
    usuario = obtenerUsuario(request, object_id)
    if usuario == 'No existe el objecto usuario':
        return render_to_response('error.html',{'error':'No existe el objecto usuario', 'archivo': 'view de usuarios', 'linea': 'linea 20'})
    request.breadcrumbs([('Usuarios',reverse(listar_usuarios)),('Listar Publicaciones de '+usuario.get_full_name(),request.path)])
    return render_to_response('Registration_Users/publicaciones.html', {'Usuario': usuario,
                                                                 'books': Libros.objects.filter(Q(creado_por=usuario.username) | Q(autores__autor_interno__id__exact=usuario.id)).distinct(),
                                                                 'magazines': Revistas.objects.filter(Q(creado_por=usuario.username) | Q(autores__autor_interno__id__exact=usuario.id)).distinct(),
                                                                 'tesis': Tesis.objects.filter(Q(creado_por=usuario.username) | Q(autores__autor_interno__id__exact=usuario.id)).distinct(),
                                                                 'papers': Papers.objects.filter(Q(creado_por=usuario.username) | Q(autores__autor_interno__id__exact=usuario.id)).distinct(),
                                                                 'reports': ReportesTecnicos.objects.filter(Q(creado_por=usuario.username) | Q(autores__autor_interno__id__exact=usuario.id)).distinct(),
                                                                 'conferences': Conferencias.objects.filter(Q(creado_por=usuario.username) | Q(autores__autor_interno__id__exact=usuario.id)).distinct(),
                                                                 'user': request.user}, context_instance=RequestContext(request))

    
#PERMISOS Y TIPOS DE USUARIOS(GRUPOS)-------------------------------------

def list_usertype_view(request):
    request.breadcrumbs([('Lista de Usuarios',request.path)])
    u = User.objects.all()
    user_list = []
    for users in u: 
        user_list.append({'euser':users,'eut':users.groups.all()})
        
    return render_to_response('Registration_Users/list.html',{'user':request.user,'user_list':user_list},context_instance=RequestContext(request))

def remover_cargos(request, object_id=0):
    list_get = request.GET.getlist('assigned_cargos')
    if list_get is not None:
        this_user = obtenerUsuario(request, object_id)
        for item in list_get:
            this_user.get_profile().cargo.remove(CargoAcademico.objects.get(Cargo__exact=item))
    return HttpResponseRedirect(reverse(mostrar_cargos, args=[object_id]))

def asignar_cargos(request, object_id=0):
    list_get = request.GET.getlist('available_cargos')
    if list_get is not None:
        this_user = obtenerUsuario(request, object_id)
        for item in list_get:
            this_user.get_profile().cargo.add(CargoAcademico.objects.get(Cargo__exact=item))
    return HttpResponseRedirect(reverse(mostrar_cargos, args=[object_id]))

def mostrar_cargos(request, object_id=0):
    request.breadcrumbs([('Listar Usuarios',reverse(list_usertype_view)),('Asignar Cargos a Usuarios',request.path)])
    available_cargos = CargoAcademico.objects.all()
    u = obtenerUsuario(request, object_id)
    resultado = []
    list_assigned = []
    try:
        for item in u.get_profile().cargo.all():
            list_assigned.append(item.Cargo)
        for item in available_cargos:
            if not item.Cargo in list_assigned:
                resultado.append(item.Cargo)
    except ObjectDoesNotExist:
        pass

    return render_to_response('Registration_Users/mostrar_cargos.html',{'objuser': u,
                                                                        'assigned_cargos':list_assigned,
                                                                        'available_cargos':resultado,
                                                                        'user':request.user
                                                                        },context_instance=RequestContext(request))

def remover_permisos(request, object_id=0):
    if request.method == 'GET':
        list_get = request.GET.getlist('assigned_perm') 
        if list_get is not None:
            this_user = obtenerUsuario(request, object_id)
            #this_user.user_permissions = list_get
            for item in list_get:                
                    this_user.user_permissions.remove(Permission.objects.get(name__exact=item))
        return HttpResponseRedirect(reverse(mostrar_permisos, args=[object_id]))
    
def mostrar_permisos(request,object_id=0):
    request.breadcrumbs([('Tipos de usuarios',reverse(index)),('Listar Usuarios',reverse(list_usertype_view)),('Asignar permisos a Usuarios',request.path)])
    available_perms = Permission.objects.filter(     Q(codename='add_permission')|Q(codename='change_permission')|Q(codename='delete_permission')|
                                                     Q(codename='add_group')|Q(codename='change_group')|Q(codename='delete_group')|
                                                     Q(codename='add_departamentos')|Q(codename='change_departamentos')|Q(codename='delete_departamentos')|
                                                     Q(codename='add_gruposdeinvestigacion')|Q(codename='change_gruposdeinvestigacion')|Q(codename='delete_gruposdeinvestigacion')|
                                                     Q(codename='add_lineasdeinvestigacion')|Q(codename='change_lineasdeinvestigacion')|Q(codename='delete_lineasdeinvestigacion')|
                                                     Q(codename='add_proyectos')|Q(codename='change_proyectos')|Q(codename='delete_proyectos')|
                                                     Q(codename='add_partners')|Q(codename='change_partners')|Q(codename='delete_partners')|
                                                     Q(codename='add_publicaciones')|Q(codename='change_publicaciones')|Q(codename='delete_publicaciones')|
                                                     Q(codename='add_eventos')|Q(codename='change_eventos')|Q(codename='delete_eventos')   )
    u = obtenerUsuario(request, object_id)
    usertype_list = u.groups.all()
    resultado = []
    list_assigned = []
    try:

        for item in u.user_permissions.all():
            list_assigned.append(item.name)
        for item in available_perms:
            if not item.name in list_assigned:
                resultado.append(item.name)
    except ObjectDoesNotExist:
        pass    

    return render_to_response('Registration_Users/mostrar_permisos.html',{'objuser': u,
                                                               'assigned_perms':list_assigned,
                                                               'available_perms':resultado,
                                                               'usertype_list':usertype_list,
                                                               'user':request.user,},
                                                               context_instance=RequestContext(request))

def asignar_permisos(request, object_id=0):
    if request.method == 'GET':
        list_get = request.GET.getlist('available_perm')
        if list_get is not None:
            this_user = obtenerUsuario(request, object_id)
            #this_user.user_permissions = list_get
            for item in list_get:
                this_user.user_permissions.add(Permission.objects.get(name__exact=item))
        return HttpResponseRedirect(reverse(mostrar_permisos, args=[object_id]))

def register_usertype_view(request):
    c = {}
    request.breadcrumbs([('Tipos de usuarios',reverse(index)),('Nuevo Tipo Usuario',request.path)])
    
    if request.method == 'POST':
        form = UserTypeForm(request.POST.copy())
        if form.is_valid():
            form.save(commit=True)
            return render_to_response('Registration_Users/add_success.html',{'user':request.user},context_instance=RequestContext(request))
        else:
            c.update({'errors':'Hubo un error al generar el tipo de usuario. Vuelva a intentarlo.',})
            return render_to_response('Registration_Users/error.html',c,context_instance=RequestContext(request))
    else:
        form = UserTypeForm()
        c.update(csrf(request))
        c.update({'form':form,'user':request.user,})
        return render_to_response('Registration_Users/edit_usertype.html',c,context_instance=RequestContext(request))

def asignar_tipos(request,object_id=0):
    request.breadcrumbs([('Tipos de usuarios',reverse(index)),('Asignar tipo de Usuario a Usuario',request.path)])
    
    u = obtenerUsuario(request, object_id)
    if request.method == 'GET':
        usertype_list = request.GET.getlist('usertype')
        if usertype_list is not None:
            u.groups = usertype_list
        
        return HttpResponseRedirect(reverse(mostrar_tipos, args=[object_id]))

def crear_tipo_usuario(request):
    if request.method == 'POST':
        try:
            nombretipo = request.POST['name']
            grupo = DjangoGroup(name=nombretipo)
            grupo.save()
        except IntegrityError:
            pass
    return HttpResponseRedirect(reverse(mostrar_tipos, args=[int(request.user.id)]))

def mostrar_tipos(request, object_id=0):
    request.breadcrumbs([('Tipos de usuarios',reverse(list_usertype_view)),('Asignar Tipo de Usuario',request.path)])
    
    u = obtenerUsuario(request, object_id)
    usertype_list = []
    for item in u.groups.all():
        usertype_list.append(item.name)
    types = Group.objects.all()
   
    return render_to_response('Registration_Users/mostrar_tipos.html',{'objuser': u,
                                                          'usertype_list':usertype_list,
                                                          'types':types,
                                                          'user':request.user},
                                                          context_instance=RequestContext(request))
    
    
def ajax_add_permission_view(request,key_xhr):
    response_dict = {}
    sp = request.POST.getlist('option')
    gp = list(Permission.objects.filter(permiso__icontains = sp[0]))

    if gp == []:
        np = Permission(permiso=sp[0],descripcion='No hay descripcion')
        np.save()
        response_dict.update({'ok': True,
                              'perm':sp[0]})
    else:
        response_dict.update({'errors':'El permiso ya esta registrado'})

    return HttpResponse(simplejson.dumps(response_dict),mimetype='application/javascript')

def ajax_add_cargos_view(request,key_xhr):
    response_dict = {}
    sp = request.POST.getlist('option')
    gp = list(CargoAcademico.objects.filter(Cargo__icontains = sp[0]))

    if gp == []:
        np = CargoAcademico(Cargo=sp[0],descripcion='No hay descripcion')
        np.save()
        response_dict.update({'ok': True,
                              'cargo':np.Cargo})
    else:
        response_dict.update({'errors':'El cargo ya esta registrado'})

    return HttpResponse(simplejson.dumps(response_dict),mimetype='application/javascript')
